// 2010年版权归Go作者所有。版权所有。
// 此源代码的使用受BSD样式的约束
// 可以在许可证文件中找到的许可证。

package json

// JSON值解析器状态机。
// 就在手写的合理限度之内。
// 有些部分有点乏味，但总的来说，它很好地解决了问题
// 否则，来自多个扫描功能的通用代码
// 在此包中（压缩、缩进、检查有效等）。
// None
// 本文件从使用扫描仪的两个简单示例开始
// 在潜入扫描仪之前。

import (
	"strconv"
	"sync"
)

// Valid报告数据是否为有效的JSON编码。
func Valid(data []byte) bool {
	scan := newScanner()
	defer freeScanner(scan)
	return checkValid(data, scan) == nil
}

// checkValid验证数据是否为有效的JSON编码数据。
// 通过checkValid传入扫描以避免分配。
func checkValid(data []byte, scan *scanner) error {
	scan.reset()
	for _, c := range data {
		scan.bytes++
		if scan.step(scan, c) == scanError {
			return scan.err
		}
	}
	if scan.eof() == scanError {
		return scan.err
	}
	return nil
}

// SyntaxError是对JSON语法错误的描述。
type SyntaxError struct {
	msg    string // 错误描述
	Offset int64  // 读取偏移量字节后出错
}

func (e *SyntaxError) Error() string { return e.msg }

// 扫描程序是JSON扫描状态机。
// 调用者调用scan.reset，然后一次传递一个字节
// 通过为每个字节调用scan.step（&scan，c）。
// 返回值（称为操作码）告诉
// 调用者关于重要的解析事件，如开始
// 以及结束文字、对象和数组，以便
// 打电话的人可以随叫随到。
// 返回值scanEnd表示单个顶级
// JSON值已完成，*在*字节之前
// 刚通过考试。（指示必须按顺序延迟
// 识别数字的结尾：123是整数值还是
// 12345e+6？）的开始。
type scanner struct {
	// 该步骤是要调用以执行下一个转换的func。
	// 还尝试使用整数常量和单个func
	// 使用开关，但直接使用func快了10%
	// 在64位Mac Mini上，阅读起来更舒服。
	step func(*scanner, byte) int

	// 已达到顶级值的末尾。
	endTop bool

	// 堆栈中的数组值、对象键、对象值。
	parseState []int

	// 发生的错误，如果有的话。
	err error

	// 解码器消耗、更新的总字节数。解码（和）
	// 未通过扫描设置为零（重置）
	bytes int64
}

var scannerPool = sync.Pool{
	New: func() interface{} {
		return &scanner{}
	},
}

func newScanner() *scanner {
	scan := scannerPool.Get().(*scanner)
	// scan.reset by design不会将字节设置为零
	scan.bytes = 0
	scan.reset()
	return scan
}

func freeScanner(scan *scanner) {
	// 在极端情况下，避免占用太多内存。
	if len(scan.parseState) > 1024 {
		scan.parseState = nil
	}
	scannerPool.Put(scan)
}

// 这些值由状态转换函数返回
// 分配给scanner.state和scanner.eof方法。
// 它们提供了有关扫描当前状态的详细信息
// 打电话的人可能有兴趣知道。
// 可以忽略任何特定属性的返回值
// 调用scanner.state：如果一个调用返回scanError，
// 每次后续调用也将返回scanError。
const (
	// 持续
	scanContinue     = iota // 无趣字节
	scanBeginLiteral        // 下一个结果暗示结束！=扫描继续
	scanBeginObject         // 开始对象
	scanObjectKey           // 刚完成的对象键（字符串）
	scanObjectValue         // 刚完成的非最后一个对象值
	scanEndObject           // 结束对象（如果可能，表示scanObjectValue）
	scanBeginArray          // 开始数组
	scanArrayValue          // 刚完成的数组值
	scanEndArray            // 结束数组（如果可能，表示scanArrayValue）
	scanSkipSpace           // 空间字节；可以跳过；已知为最后一个“继续”结果

	// 停止
	scanEnd   // 顶级值在*该字节之前*结束；已知为第一个“停止”结果
	scanError // 点击一个错误，scanner.err。
)

// 这些值存储在parseState堆栈中。
// 它们给出了复合值的当前状态
// 正在扫描。如果解析器位于嵌套值内
// parseState描述嵌套状态，最外层为条目0。
const (
	parseObjectKey   = iota // 正在分析对象键（冒号之前）
	parseObjectValue        // 分析对象值（冒号后）
	parseArrayValue         // 解析数组值
)

// 这将限制最大嵌套深度以防止堆栈溢出。
// 这是https允许的：
const maxNestingDepth = 10000

// 重置为扫描仪的使用做好准备。
// 必须在调用s.step之前调用它。
func (s *scanner) reset() {
	s.step = stateBeginValue
	s.parseState = s.parseState[0:0]
	s.err = nil
	s.endTop = false
}

// eof告诉扫描仪已到达输入的末尾。
// 它返回的扫描状态与s.step相同。
func (s *scanner) eof() int {
	if s.err != nil {
		return scanError
	}
	if s.endTop {
		return scanEnd
	}
	s.step(s, ' ')
	if s.endTop {
		return scanEnd
	}
	if s.err == nil {
		s.err = &SyntaxError{"unexpected end of JSON input", s.bytes}
	}
	return scanError
}

// pushParseState将新的解析状态p推送到解析堆栈上。
// 如果超过maxNestingDepth，则返回错误状态，否则返回successState。
func (s *scanner) pushParseState(c byte, newParseState int, successState int) int {
	s.parseState = append(s.parseState, newParseState)
	if len(s.parseState) <= maxNestingDepth {
		return successState
	}
	return s.error(c, "exceeded max depth")
}

// popParseState从堆栈中弹出一个解析状态（已获得）
// 并相应地更新s.step。
func (s *scanner) popParseState() {
	n := len(s.parseState) - 1
	s.parseState = s.parseState[0:n]
	if n == 0 {
		s.step = stateEndTop
		s.endTop = true
	} else {
		s.step = stateEndValue
	}
}

func isSpace(c byte) bool {
	return c <= ' ' && (c == ' ' || c == '\t' || c == '\r' || c == '\n')
}

// stateBeginValueOrEmpty是读取“[]”后的状态。
func stateBeginValueOrEmpty(s *scanner, c byte) int {
	if isSpace(c) {
		return scanSkipSpace
	}
	if c == ']' {
		return stateEndValue(s, c)
	}
	return stateBeginValue(s, c)
}

// stateBeginValue是输入开头的状态。
func stateBeginValue(s *scanner, c byte) int {
	if isSpace(c) {
		return scanSkipSpace
	}
	switch c {
	case '{':
		s.step = stateBeginStringOrEmpty
		return s.pushParseState(c, parseObjectKey, scanBeginObject)
	case '[':
		s.step = stateBeginValueOrEmpty
		return s.pushParseState(c, parseArrayValue, scanBeginArray)
	case '"':
		s.step = stateInString
		return scanBeginLiteral
	case '-':
		s.step = stateNeg
		return scanBeginLiteral
	case '0': // 0.123的开始
		s.step = state0
		return scanBeginLiteral
	case 't': // 真正的开始
		s.step = stateT
		return scanBeginLiteral
	case 'f': // 假开始
		s.step = stateF
		return scanBeginLiteral
	case 'n': // 空的开始
		s.step = stateN
		return scanBeginLiteral
	}
	if '1' <= c && c <= '9' { // 1234.5的开始
		s.step = state1
		return scanBeginLiteral
	}
	return s.error(c, "looking for beginning of value")
}

// stateBeginStringOrEmpty是读取`{`后的状态。
func stateBeginStringOrEmpty(s *scanner, c byte) int {
	if isSpace(c) {
		return scanSkipSpace
	}
	if c == '}' {
		n := len(s.parseState)
		s.parseState[n-1] = parseObjectValue
		return stateEndValue(s, c)
	}
	return stateBeginString(s, c)
}

// stateBeginString是读取`{“key”：value`后的状态。
func stateBeginString(s *scanner, c byte) int {
	if isSpace(c) {
		return scanSkipSpace
	}
	if c == '"' {
		s.step = stateInString
		return scanBeginLiteral
	}
	return s.error(c, "looking for beginning of object key string")
}

// stateEndValue是完成值后的状态，
// 例如在读了`{}`或``真`或`[“x”`之后。
func stateEndValue(s *scanner, c byte) int {
	n := len(s.parseState)
	if n == 0 {
		// 在当前字节之前完成顶层。
		s.step = stateEndTop
		s.endTop = true
		return stateEndTop(s, c)
	}
	if isSpace(c) {
		s.step = stateEndValue
		return scanSkipSpace
	}
	ps := s.parseState[n-1]
	switch ps {
	case parseObjectKey:
		if c == ':' {
			s.parseState[n-1] = parseObjectValue
			s.step = stateBeginValue
			return scanObjectKey
		}
		return s.error(c, "after object key")
	case parseObjectValue:
		if c == ',' {
			s.parseState[n-1] = parseObjectKey
			s.step = stateBeginString
			return scanObjectValue
		}
		if c == '}' {
			s.popParseState()
			return scanEndObject
		}
		return s.error(c, "after object key:value pair")
	case parseArrayValue:
		if c == ',' {
			s.step = stateBeginValue
			return scanArrayValue
		}
		if c == ']' {
			s.popParseState()
			return scanEndArray
		}
		return s.error(c, "after array element")
	}
	return s.error(c, "")
}

// stateEndTop是完成顶级值后的状态，
// 例如在读了`{}`或`[1,2,3]`之后。
// 现在只能看到空格字符。
func stateEndTop(s *scanner, c byte) int {
	if !isSpace(c) {
		// 在下一次调用时抱怨没有空格字节。
		s.error(c, "after top-level value")
	}
	return scanEnd
}

// stateInString是读取``后的状态。
func stateInString(s *scanner, c byte) int {
	if c == '"' {
		s.step = stateEndValue
		return scanContinue
	}
	if c == '\\' {
		s.step = stateInStringEsc
		return scanContinue
	}
	if c < 0x20 {
		return s.error(c, "in string literal")
	}
	return scanContinue
}

// stateInStringEsc是在带引号的字符串中读取““\”后的状态。
func stateInStringEsc(s *scanner, c byte) int {
	switch c {
	case 'b', 'f', 'n', 'r', 't', '\\', '/', '"':
		s.step = stateInString
		return scanContinue
	case 'u':
		s.step = stateInStringEscU
		return scanContinue
	}
	return s.error(c, "in string escape code")
}

// stateInStringEscU是在带引号的字符串中读取““\u”后的状态。
func stateInStringEscU(s *scanner, c byte) int {
	if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {
		s.step = stateInStringEscU1
		return scanContinue
	}
	// 数字
	return s.error(c, "in \\u hexadecimal character escape")
}

// stateInStringEscU1是在带引号的字符串中读取““\u1”后的状态。
func stateInStringEscU1(s *scanner, c byte) int {
	if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {
		s.step = stateInStringEscU12
		return scanContinue
	}
	// 数字
	return s.error(c, "in \\u hexadecimal character escape")
}

// stateInStringEscU12是在带引号的字符串中读取““\u12”后的状态。
func stateInStringEscU12(s *scanner, c byte) int {
	if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {
		s.step = stateInStringEscU123
		return scanContinue
	}
	// 数字
	return s.error(c, "in \\u hexadecimal character escape")
}

// stateInStringEscU123是在引用字符串期间读取““\u123”后的状态。
func stateInStringEscU123(s *scanner, c byte) int {
	if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {
		s.step = stateInString
		return scanContinue
	}
	// 数字
	return s.error(c, "in \\u hexadecimal character escape")
}

// stateNeg是在数字期间读取“-”后的状态。
func stateNeg(s *scanner, c byte) int {
	if c == '0' {
		s.step = state0
		return scanContinue
	}
	if '1' <= c && c <= '9' {
		s.step = state1
		return scanContinue
	}
	return s.error(c, "in numeric literal")
}

// state1是在数字期间读取非零整数后的状态，
// 例如在读了'1'或'100'之后，而不是读了'0'。
func state1(s *scanner, c byte) int {
	if '0' <= c && c <= '9' {
		s.step = state1
		return scanContinue
	}
	return state0(s, c)
}

// state0是在数字处理过程中读取“0”后的状态。
func state0(s *scanner, c byte) int {
	if c == '.' {
		s.step = stateDot
		return scanContinue
	}
	if c == 'e' || c == 'E' {
		s.step = stateE
		return scanContinue
	}
	return stateEndValue(s, c)
}

// stateDot是读取数字中的整数和小数点后的状态，
// 比如读了“1”之后。
func stateDot(s *scanner, c byte) int {
	if '0' <= c && c <= '9' {
		s.step = stateDot0
		return scanContinue
	}
	return s.error(c, "after decimal point in numeric literal")
}

// stateDot0是读取整数、小数点和后续值后的状态
// 数字的位数，如在读取'3.14'之后。
func stateDot0(s *scanner, c byte) int {
	if '0' <= c && c <= '9' {
		return scanContinue
	}
	if c == 'e' || c == 'E' {
		s.step = stateE
		return scanContinue
	}
	return stateEndValue(s, c)
}

// stateE是读取数字中尾数和e后的状态，
// 例如在读了'314e'或'0.314e'之后。
func stateE(s *scanner, c byte) int {
	if c == '+' || c == '-' {
		s.step = stateESign
		return scanContinue
	}
	return stateESign(s, c)
}

// StateSign是读取尾数、e并在数字中签名后的状态，
// 例如在读了'314e-'或'0.314e+'之后。
func stateESign(s *scanner, c byte) int {
	if '0' <= c && c <= '9' {
		s.step = stateE0
		return scanContinue
	}
	return s.error(c, "in exponent of numeric literal")
}

// State0是读取尾数、e、可选符号后的状态，
// 以及数字中指数的至少一位，
// 例如在读了'314e-2'或'0.314e+1'或'3.14e0'之后。
func stateE0(s *scanner, c byte) int {
	if '0' <= c && c <= '9' {
		return scanContinue
	}
	return stateEndValue(s, c)
}

// stateT是读取't'后的状态。
func stateT(s *scanner, c byte) int {
	if c == 'r' {
		s.step = stateTr
		return scanContinue
	}
	return s.error(c, "in literal true (expecting 'r')")
}

// stateTr是读取'tr'后的状态。
func stateTr(s *scanner, c byte) int {
	if c == 'u' {
		s.step = stateTru
		return scanContinue
	}
	return s.error(c, "in literal true (expecting 'u')")
}

// stateTru是读取'tru'后的状态。
func stateTru(s *scanner, c byte) int {
	if c == 'e' {
		s.step = stateEndValue
		return scanContinue
	}
	return s.error(c, "in literal true (expecting 'e')")
}

// stateF是读取'f'后的状态。
func stateF(s *scanner, c byte) int {
	if c == 'a' {
		s.step = stateFa
		return scanContinue
	}
	return s.error(c, "in literal false (expecting 'a')")
}

// stateFa是读取'fa'后的状态。
func stateFa(s *scanner, c byte) int {
	if c == 'l' {
		s.step = stateFal
		return scanContinue
	}
	return s.error(c, "in literal false (expecting 'l')")
}

// stateFal是读取'fal'后的状态。
func stateFal(s *scanner, c byte) int {
	if c == 's' {
		s.step = stateFals
		return scanContinue
	}
	return s.error(c, "in literal false (expecting 's')")
}

// stateFals是读取'fals'后的状态。
func stateFals(s *scanner, c byte) int {
	if c == 'e' {
		s.step = stateEndValue
		return scanContinue
	}
	return s.error(c, "in literal false (expecting 'e')")
}

// stateN是读取'n'后的状态。
func stateN(s *scanner, c byte) int {
	if c == 'u' {
		s.step = stateNu
		return scanContinue
	}
	return s.error(c, "in literal null (expecting 'u')")
}

// stateNu是读取'nu'后的状态。
func stateNu(s *scanner, c byte) int {
	if c == 'l' {
		s.step = stateNul
		return scanContinue
	}
	return s.error(c, "in literal null (expecting 'l')")
}

// stateNul是读取'nul'后的状态。
func stateNul(s *scanner, c byte) int {
	if c == 'l' {
		s.step = stateEndValue
		return scanContinue
	}
	return s.error(c, "in literal null (expecting 'l')")
}

// stateError是到达语法错误后的状态，
// 例如在阅读了“[1}”或“5.1.2”之后。
func stateError(s *scanner, c byte) int {
	return scanError
}

// 错误记录错误并切换到错误状态。
func (s *scanner) error(c byte, context string) int {
	s.step = stateError
	s.err = &SyntaxError{"invalid character " + quoteChar(c) + " " + context, s.bytes}
	return scanError
}

// quoteChar将c格式化为带引号的字符文字
func quoteChar(c byte) string {
	// 特殊情况-不同于带引号的字符串
	if c == '\'' {
		return `'\''`
	}
	if c == '"' {
		return `'"'`
	}

	// 使用带不同引号的带引号字符串
	s := strconv.Quote(string(c))
	return "'" + s[1:len(s)-1] + "'"
}
